<template>
    <a-form ref="Form" autocomplete="off" :model="FormValue" :rules :labelCol :layout :labelAlign>
        <a-row :gutter="0">
            <a-col :span="layout == 'vertical' ? 24 : 6" v-for="item in options">
                <a-form-item :label="item.label" :name="item.name">
                    <template v-if="item.slotLabel" #label>
                        <component :is="item.slotLabel.component" v-bind="item.slotLabel.attrs">
                            {{ item.slotLabel.attrs.value }}
                        </component>
                    </template>
                    <component v-if="item.component.includes('Upload')" :is="item.component"
                        v-model:fileList="FormValue[item.name as keyof typeof FormValue]" v-bind="item.attrs">
                        <template v-for="{ name, component } in item.slots" #[name]>
                            <component :is="component" />
                        </template>
                    </component>
                    <component v-else :is="item.component"
                        v-model:value="FormValue[item.name as keyof typeof FormValue]" v-bind="item.attrs">
                        <template v-for="{ name, component } in item.slots" #[name]>
                            <component :is="component" />
                        </template>
                    </component>
                    <slot v-if="item.componentSlot" name="componentSlot" />
                </a-form-item>
            </a-col>
            <a-col :span="layout == 'vertical' ? 24 : 6">
                <slot name="footer" />
            </a-col>
        </a-row>
        <slot name="custom" />
    </a-form>
</template>

<script lang="ts" setup>
// : md = "{ span: layout == 'inline' ? 8 : 24 }"
// : sm = "{ span: layout == 'inline' ? 6 : 24 }" : xs = "{span:24}"

import { message } from 'ant-design-vue'
import { computed, nextTick, onMounted, ref, watch } from 'vue'
import type { Component } from 'vue'


interface Props {
    options: customComponent[],
    FormValue: object,
    rules?: object,
    labelCol: object,
    layout: string,
    labelAlign: string,

}
interface customComponent {
    component: string,
    name: string,
    tirgger: string,
    label?: string,
    attrs?: Object,
    slots?: {
        name: string,
        component: Component
    }[]
    slotLabel?: {
        component: Component,
        attrs: {
            value?: string
            [key: string]: any
        }
    }
    componentSlot?: boolean
}



const props = defineProps<Props>()
const Form = ref()



function resetFields() {
    Form.value.resetFields()
}
async function validate(fn: Function) {
    await nextTick()
    Form.value.validate()
        .then((res: any) => {
            // message.success('表单校验成功！')
            fn()
        })
        .catch((err: any) => {
            console.log(err);
            message.error('表单校验失败！')
        })
}


defineExpose({
    validate, resetFields, Form
})
</script>

<style lang="scss" scoped>
.ant-form {
    width: 100%;

    .ant-row {
        width: 100%;
    }
}
</style>